import SwiftUI

struct FreeRecordingView: View {
    @EnvironmentObject var sensor: SensorRecorder
    @AppStorage("userName") private var userName: String = ""
    @Environment(\.dismiss) private var dismiss
    
    // 录制状态
    @State private var isRecording: Bool = false
    @State private var isChewing: Bool = false
    @State private var elapsedTime: TimeInterval = 0
    
    // Session 数据
    @State private var session = FreeRecordingSession()
    @State private var currentSegmentStartDate: Date?
    @State private var currentSegmentStartIndex: Int = 0
    
    // UI 状态
    @State private var showNoteSheet: Bool = false
    @State private var noteText: String = ""
    @State private var showSaveButton: Bool = false
    
    // 上传状态
    @State private var isUploading: Bool = false
    @State private var uploadError: String?
    @State private var uploadSuccess: Bool = false
    
    // 定时器
    @State private var timer: Timer?
    @State private var currentSegmentStartDate: Date?
    @State private var currentSegmentStartSampleIndex: Int = 0
    
    @State private var showNoteSheet: Bool = false
    @State private var noteText: String = ""
    @State private var isUploading: Bool = false
    @State private var uploadError: String?
    @State private var uploadSuccess: Bool = false
    @State private var hasFinishedRecording: Bool = false  // 标记是否已完成记录但未上传
    
    @State private var elapsedTime: TimeInterval = 0
    @State private var timer: Timer?
    
    var body: some View {
        ZStack {
            // 背景渐变
            LinearGradient(colors: [.black.opacity(0.95), .purple.opacity(0.5), .pink.opacity(0.3)], startPoint: .topLeading, endPoint: .bottomTrailing)
                .ignoresSafeArea()
            
            VStack(spacing: 24) {
                // 标题
                VStack(spacing: 8) {
                    Image(systemName: "record.circle.fill")
                        .font(.system(size: 50, weight: .bold))
                        .foregroundStyle(LinearGradient(colors: [.purple, .pink, .orange], startPoint: .topLeading, endPoint: .bottomTrailing))
                    
                    Text("自由记录")
                        .font(.system(.title, design: .rounded).weight(.bold))
                        .foregroundColor(.white)
                    
                    Text("记录完整用餐过程")
                        .font(.system(.subheadline, design: .rounded))
                        .foregroundColor(.white.opacity(0.7))
                }
                .padding(.top, 40)
                
                Spacer()
                
                // 状态显示
                VStack(spacing: 20) {
                    // 总时长
                    VStack(spacing: 8) {
                        Text("总时长")
                            .font(.system(.caption, design: .rounded))
                            .foregroundColor(.white.opacity(0.7))
                        Text(formatTime(elapsedTime))
                            .font(.system(size: 48, weight: .bold, design: .rounded))
                            .foregroundColor(.white)
                    }
                    
                    // 当前状态
                    HStack(spacing: 12) {
                        Circle()
                            .fill(isRecording ? (isChewing ? Color.green : Color.orange) : Color.gray)
                            .frame(width: 12, height: 12)
                        
                        Text(isRecording ? (isChewing ? "咀嚼中" : "非咀嚼中") : "未开始")
                            .font(.system(.headline, design: .rounded))
                            .foregroundColor(.white)
                    }
                    .padding(.horizontal, 20)
                    .padding(.vertical, 10)
                    .background(.white.opacity(0.1))
                    .cornerRadius(20)
                    
                    // 实时传感器数据
                    if isRecording {
                        VStack(spacing: 12) {
                            SensorDataRow(
                                title: "加速度计",
                                icon: "arrow.up.and.down.and.arrow.left.and.right",
                                color: .cyan,
                                xValue: sensor.currentAccX,
                                yValue: sensor.currentAccY,
                                zValue: sensor.currentAccZ,
                                unit: "g"
                            )
                            
                            SensorDataRow(
                                title: "陀螺仪",
                                icon: "gyroscope",
                                color: .orange,
                                xValue: sensor.currentGyroX,
                                yValue: sensor.currentGyroY,
                                zValue: sensor.currentGyroZ,
                                unit: "rad/s"
                            )
                        }
                    }
                    
                    // 统计信息
                    HStack(spacing: 30) {
                        StatCard(title: "咀嚼段", value: "\(session.chewingSegments.count)", color: .green)
                        StatCard(title: "非咀嚼段", value: "\(session.nonChewingSegments.count)", color: .orange)
                        StatCard(title: "样本数", value: "\(sensor.sampleCount)", color: .cyan)
                    }
                }
                
                Spacer()
                
                // 控制按钮
                VStack(spacing: 16) {
                    if !isRecording && !hasFinishedRecording {
                        // 开始按钮
                        Button {
                            startRecording()
                        } label: {
                            Label("开始咀嚼", systemImage: "play.fill")
                                .font(.system(.title3, design: .rounded).weight(.semibold))
                                .foregroundColor(.white)
                                .frame(maxWidth: .infinity)
                                .padding(.vertical, 18)
                                .background(LinearGradient(colors: [.green, .teal], startPoint: .leading, endPoint: .trailing))
                                .cornerRadius(16)
                        }
                    } else if hasFinishedRecording {
                        // 已完成记录，显示保存按钮
                        Button {
                            showNoteSheet = true
                        } label: {
                            Label("保存记录", systemImage: "square.and.arrow.down.fill")
                                .font(.system(.title3, design: .rounded).weight(.semibold))
                                .foregroundColor(.white)
                                .frame(maxWidth: .infinity)
                                .padding(.vertical, 18)
                                .background(LinearGradient(colors: [.blue, .purple], startPoint: .leading, endPoint: .trailing))
                                .cornerRadius(16)
                        }
                        
                        Text("请输入备注并保存数据")
                            .font(.system(.footnote, design: .rounded))
                            .foregroundColor(.orange)
                    } else {
                        // 暂停/继续按钮
                        Button {
                            toggleChewing()
                        } label: {
                            Label(isChewing ? "停止咀嚼" : "继续咀嚼", systemImage: isChewing ? "pause.fill" : "play.fill")
                                .font(.system(.title3, design: .rounded).weight(.semibold))
                                .foregroundColor(.white)
                                .frame(maxWidth: .infinity)
                                .padding(.vertical, 18)
                                .background(LinearGradient(colors: isChewing ? [.orange, .red] : [.green, .teal], startPoint: .leading, endPoint: .trailing))
                                .cornerRadius(16)
                        }
                        
                        // 结束按钮
                        Button {
                            finishRecording()
                        } label: {
                            Label("结束记录", systemImage: "stop.fill")
                                .font(.system(.headline, design: .rounded).weight(.semibold))
                                .foregroundColor(.white)
                                .frame(maxWidth: .infinity)
                                .padding(.vertical, 16)
                                .background(.red.opacity(0.8))
                                .cornerRadius(16)
                        }
                    }
                    
                    // 取消按钮
                    if !isRecording && !hasFinishedRecording {
                        Button("取消") {
                            dismiss()
                        }
                        .font(.system(.body, design: .rounded))
                        .foregroundColor(.white.opacity(0.7))
                    }
                }
                .padding(.horizontal, 30)
                .padding(.bottom, 40)
            }
        }
        .navigationBarBackButtonHidden(isRecording)
        .onAppear {
            print("[FreeRecordingView] 页面出现")
            // 确保初始状态清洁
            showNoteSheet = false
            hasFinishedRecording = false
        }
        .onDisappear {
            print("[FreeRecordingView] 页面消失")
            // 页面关闭时停止传感器
            if isRecording {
                sensor.stop()
                timer?.invalidate()
                timer = nil
            }
        }
        .sheet(isPresented: $showNoteSheet) {
            NoteInputSheet(noteText: $noteText) { note in
                session.note = note
                showNoteSheet = false
                hasFinishedRecording = false  // 开始上传后清除标记
                Task {
                    await uploadDataToServer(note: note)
                }
                noteText = ""
            }
            .presentationDetents([.height(260), .medium])
            .presentationCornerRadius(20)
            .interactiveDismissDisabled(true)  // 禁止手势关闭
        }
        .overlay {
            if isUploading {
                UploadingOverlay()
            }
        }
        .alert("上传失败", isPresented: .constant(uploadError != nil)) {
            Button("确定") {
                uploadError = nil
                dismiss()
            }
        } message: {
            Text(uploadError ?? "")
        }
        .alert("上传成功", isPresented: $uploadSuccess) {
            Button("确定") {
                uploadSuccess = false
                dismiss()
            }
        } message: {
            Text("数据已成功保存到服务器")
        }
    }
    
    // MARK: - Recording Control
    private func startRecording() {
        isRecording = true
        isChewing = true
        session = FreeRecordingSession()
        currentSegmentStartDate = Date()
        currentSegmentStartSampleIndex = 0
        
        // 开始传感器采集
        sensor.start(rateHz: 50)
        
        // 开始计时
        elapsedTime = 0
        timer = Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { _ in
            elapsedTime = Date().timeIntervalSince(session.startDate)
        }
    }
    
    private func toggleChewing() {
        // 保存当前段
        saveCurrentSegment()
        
        // 切换状态
        isChewing.toggle()
        
        // 开始新段
        currentSegmentStartDate = Date()
        currentSegmentStartSampleIndex = sensor.rawSamples.count
    }
    
    private func saveCurrentSegment() {
        guard let startDate = currentSegmentStartDate else { return }
        
        let endDate = Date()
        let endIndex = sensor.rawSamples.count
        
        // 提取当前段的样本
        let segmentRawSamples = Array(sensor.rawSamples[currentSegmentStartSampleIndex..<endIndex])
        let segmentLinSamples = Array(sensor.linSamples[currentSegmentStartSampleIndex..<endIndex])
        
        let segment = RecordingSegment(
            type: isChewing ? .chewing : .nonChewing,
            startDate: startDate,
            endDate: endDate,
            rawSamples: segmentRawSamples,
            linSamples: segmentLinSamples
        )
        
        session.segments.append(segment)
    }
    
    private func finishRecording() {
        // 保存最后一段
        saveCurrentSegment()
        
        // 停止传感器
        sensor.stop()
        timer?.invalidate()
        timer = nil
        
        isRecording = false
        session.endDate = Date()
        
        // 只有在有数据时才标记为已完成，但不自动弹出备注框
        if sensor.sampleCount > 0 {
            hasFinishedRecording = true
            // 不再自动弹出，等待用户点击保存按钮
        }
    }
    
    // MARK: - Upload
    private func uploadDataToServer(note: String) async {
        await MainActor.run {
            isUploading = true
        }
        
        do {
            // 1. 创建完整数据文件（包含所有样本）
            let completeRawSamples = sensor.rawSamples
            let completeLinSamples = sensor.linSamples
            
            // 2. 准备上传数据
            let timestamp = Int(Date().timeIntervalSince1970)
            
            // 3. 为每个段创建文件并上传（按时间顺序）
            for (index, segment) in session.segments.enumerated() {
                let segmentTimestamp = Int(segment.startDate.timeIntervalSince1970)
                
                // 创建段文件
                let rawURL = try createSegmentCSV(
                    samples: segment.rawSamples,
                    type: .raw,
                    segmentType: segment.type,
                    index: index
                )
                let linURL = try createSegmentCSV(
                    samples: segment.linSamples,
                    type: .linear,
                    segmentType: segment.type,
                    index: index
                )
                
                // 上传文件到 OSS
                let rawObjectKey = "chew_data/\(userName)/\(segmentTimestamp)_\(segment.type.rawValue)_\(index)_raw.csv"
                let linObjectKey = "chew_data/\(userName)/\(segmentTimestamp)_\(segment.type.rawValue)_\(index)_lin.csv"
                
                let rawOSSUrl = try await OSSUploadService.shared.uploadFile(fileURL: rawURL, objectKey: rawObjectKey)
                let linOSSUrl = try await OSSUploadService.shared.uploadFile(fileURL: linURL, objectKey: linObjectKey)
                
                // 调用后端接口保存该段的数据（一次调用，包含 raw 和 lin 两个 URL，并传入 sessionUUID）
                try await ChewDataService.shared.saveChewData(
                    scenario: "自由记录-\(segment.type.rawValue)",
                    note: note,
                    userName: userName,
                    duration: segment.duration,
                    rawCsvUrl: rawOSSUrl,
                    linCsvUrl: linOSSUrl,
                    timestamp: segment.startDate,
                    sessionUUID: session.sessionUUID
                )
            }
            
            // 4. 创建并上传完整文件
            let completeRawURL = try createCompleteCSV(samples: completeRawSamples, type: .raw)
            let completeLinURL = try createCompleteCSV(samples: completeLinSamples, type: .linear)
            
            let completeRawObjectKey = "chew_data/\(userName)/\(timestamp)_complete_raw.csv"
            let completeLinObjectKey = "chew_data/\(userName)/\(timestamp)_complete_lin.csv"
            
            // 5. 上传完整文件
            let completeRawOSSUrl = try await OSSUploadService.shared.uploadFile(fileURL: completeRawURL, objectKey: completeRawObjectKey)
            let completeLinOSSUrl = try await OSSUploadService.shared.uploadFile(fileURL: completeLinURL, objectKey: completeLinObjectKey)
            
            try await ChewDataService.shared.saveChewData(
                scenario: "自由记录-complete",
                note: note,
                userName: userName,
                duration: session.totalDuration,
                rawCsvUrl: completeRawOSSUrl,
                linCsvUrl: completeLinOSSUrl,
                timestamp: session.startDate,
                sessionUUID: session.sessionUUID
            )
            
            // 6. 成功
            await MainActor.run {
                isUploading = false
                uploadSuccess = true
            }
            
        } catch {
            await MainActor.run {
                isUploading = false
                uploadError = error.localizedDescription
            }
        }
    }
    
    private func createSegmentCSV(samples: [Any], type: CSVType, segmentType: SegmentType, index: Int) throws -> URL {
        let dir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
        let fileName = "\(userName)_\(segmentType.rawValue)_\(index)_\(type.rawValue).csv"
        let fileURL = dir.appendingPathComponent(fileName)
        
        let csvContent: String
        if type == .raw, let rawSamples = samples as? [RawSample] {
            csvContent = buildRawCSV(samples: rawSamples)
        } else if type == .linear, let linSamples = samples as? [LinSample] {
            csvContent = buildLinCSV(samples: linSamples)
        } else {
            throw NSError(domain: "", code: -1, userInfo: [NSLocalizedDescriptionKey: "Invalid sample type"])
        }
        
        try csvContent.data(using: .utf8)?.write(to: fileURL, options: .atomic)
        return fileURL
    }
    
    private func createCompleteCSV(samples: [Any], type: CSVType) throws -> URL {
        let dir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
        let fileName = "\(userName)_complete_\(type.rawValue).csv"
        let fileURL = dir.appendingPathComponent(fileName)
        
        let csvContent: String
        if type == .raw, let rawSamples = samples as? [RawSample] {
            csvContent = buildRawCSV(samples: rawSamples)
        } else if type == .linear, let linSamples = samples as? [LinSample] {
            csvContent = buildLinCSV(samples: linSamples)
        } else {
            throw NSError(domain: "", code: -1, userInfo: [NSLocalizedDescriptionKey: "Invalid sample type"])
        }
        
        try csvContent.data(using: .utf8)?.write(to: fileURL, options: .atomic)
        return fileURL
    }
    
    private func buildRawCSV(samples: [RawSample]) -> String {
        var s = "timestamp,ax,ay,az,wx,wy,wz\n"
        for r in samples {
            s += String(format: "%.6f,%.6f,%.6f,%.6f,%.6f,%.6f,%.6f\n", r.t, r.ax, r.ay, r.az, r.wx, r.wy, r.wz)
        }
        return s
    }
    
    private func buildLinCSV(samples: [LinSample]) -> String {
        var s = "timestamp,ax_lin,ay_lin,az_lin\n"
        for v in samples {
            s += String(format: "%.6f,%.6f,%.6f,%.6f\n", v.t, v.ax_lin, v.ay_lin, v.az_lin)
        }
        return s
    }
    
    private func formatTime(_ time: TimeInterval) -> String {
        let minutes = Int(time) / 60
        let seconds = Int(time) % 60
        return String(format: "%02d:%02d", minutes, seconds)
    }
}

// MARK: - CSV Type
enum CSVType: String {
    case raw = "raw"
    case linear = "lin"
}

// MARK: - Sensor Data Row
private struct SensorDataRow: View {
    let title: String
    let icon: String
    let color: Color
    let xValue: Double
    let yValue: Double
    let zValue: Double
    let unit: String
    
    var body: some View {
        VStack(spacing: 8) {
            HStack(spacing: 8) {
                Image(systemName: icon)
                    .font(.system(size: 14, weight: .semibold))
                    .foregroundColor(color)
                Text(title)
                    .font(.system(.caption, design: .rounded).weight(.semibold))
                    .foregroundColor(.white)
                Spacer()
            }
            
            HStack(spacing: 12) {
                AxisValue(label: "X", value: xValue, unit: unit, color: .red)
                AxisValue(label: "Y", value: yValue, unit: unit, color: .green)
                AxisValue(label: "Z", value: zValue, unit: unit, color: .blue)
            }
        }
        .padding(12)
        .background(.white.opacity(0.1))
        .cornerRadius(12)
    }
}

private struct AxisValue: View {
    let label: String
    let value: Double
    let unit: String
    let color: Color
    
    var body: some View {
        VStack(spacing: 4) {
            Text(label)
                .font(.system(.caption2, design: .rounded).weight(.bold))
                .foregroundColor(color)
            Text(String(format: "%.3f", value))
                .font(.system(.caption, design: .monospaced).weight(.medium))
                .foregroundColor(.white)
        }
        .frame(maxWidth: .infinity)
    }
}

// MARK: - Stat Card
private struct StatCard: View {
    let title: String
    let value: String
    let color: Color
    
    var body: some View {
        VStack(spacing: 6) {
            Text(value)
                .font(.system(.title2, design: .rounded).weight(.bold))
                .foregroundColor(color)
            Text(title)
                .font(.system(.caption2, design: .rounded))
                .foregroundColor(.white.opacity(0.7))
        }
        .frame(maxWidth: .infinity)
        .padding(.vertical, 12)
        .background(.white.opacity(0.1))
        .cornerRadius(12)
    }
}

// MARK: - Uploading Overlay
private struct UploadingOverlay: View {
    var body: some View {
        ZStack {
            Color.black.opacity(0.5).ignoresSafeArea()
            VStack(spacing: 20) {
                ProgressView()
                    .scaleEffect(1.5)
                    .tint(.white)
                Text("正在上传数据...")
                    .font(.system(.body, design: .rounded).weight(.medium))
                    .foregroundColor(.white)
            }
            .padding(40)
            .background(.ultraThinMaterial, in: RoundedRectangle(cornerRadius: 20))
        }
    }
}

// MARK: - Note Input Sheet
private struct NoteInputSheet: View {
    @Binding var noteText: String
    var onSave: (String) -> Void
    @Environment(\.dismiss) private var dismiss
    
    var body: some View {
        VStack(spacing: 16) {
            Capsule().fill(.secondary.opacity(0.4)).frame(width: 40, height: 5).padding(.top, 8)
            Text("记录备注")
                .font(.headline)
            Text("请输入吃的东西（必填）")
                .font(.footnote)
                .foregroundColor(.secondary)
            TextField("如：花生/苹果", text: $noteText)
                .textFieldStyle(.roundedBorder)
            HStack(spacing: 12) {
                Button("稍后填写") {
                    dismiss()
                }
                .buttonStyle(.bordered)
                
                Button("保存") {
                    onSave(noteText)
                }
                .buttonStyle(.borderedProminent)
                .disabled(noteText.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty)
            }
            Spacer(minLength: 0)
        }
        .padding(20)
    }
}
